package password;

/**
 * @author macpro
 * @date 2019-06-28
 * @function
 */
//import com.alibaba.fastjson.JSONObject;
//import org.apache.tomcat.util.codec.binary.Base64;

import com.google.gson.Gson;
import org.apaches.commons.codec.binary.Base64;
import org.json.JSONObject;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description TODO
 * @Author linmingxing
 * @Date 2019/6/14 下午4:59
 **/
public class RSAUtils {
    private static final String RSA_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDwQ9SZ1n6GU3XczbntdPerUowZU6QUx0AdYy1beYlRELj2QXAMX5cme97FQk45toHTXyKG3yl2IxrSKBa/g3j9pFpZ3sQfVf9PfpA7QmRj0gQZkpiII7MK9sh501Vb050wAqIl87/2q945rwfK8A1u1+/uuCfekB2Zi7FG7XNbxQIDAQAB";
    private static String msgEncodeBef="{\"collections\":[{\"collectionTime\":\"2019-07-01 15:34:52\",\"checkType\":\"1\",\"checkModle\":\"2\",\"checkResult\":0,\"facePhoto\":\"...\",\"userName\":\"张英杰\",\"idCardNum\":\"13112719890823001X\"}],\"location\":\"116.456451_39.908683\",\"equipmentNum\":\"FC241118370034\"}\n";

    private static Map<Integer, String> keyMap = new HashMap<Integer, String>();  //用于封装随机产生的公钥与私钥
    public static void main(String[] args) throws Exception {
        //生成公钥和私钥
        genKeyPair();
        Map map = new HashMap();
        map.put("equipmentNum","0000");
        map.put("location","116.456451_39.908683");
        List collections = new ArrayList();
        Map c1 = new HashMap();
        c1.put("collectionTime", "2019-12-11 10:19:21");
        c1.put("userName","xxx");
        c1.put("idCardNum","340221199512348377");
        c1.put("checkType","1");
        c1.put("checkModle","1");
        c1.put("facePhoto","...");
        c1.put("checkResult",1);
        collections.add(c1);
//        Map c2 = new HashMap();
//        c2.put("collectionTime", "2019-12-11 10:19:21");
//        c2.put("userName","xxx");
//        c2.put("idCardNum","340221199512348388");
//        c2.put("checkType","1");
//        c2.put("checkModle","1");
//        c2.put("facePhoto","...");
//        c2.put("checkResult",1);
//        collections.add(c2);
        map.put("collections",collections);
        //加密字符串
        String message = new Gson().toJson(map);
//        String message = JSONObject.toJSONString(map);

        System.out.println("加密前 "+message);
//        String enStr = encryptByPublicKey(message, keyMap.get(0));
//        String enStr = encryptByPublicKey(message,RSA_PUBLIC_KEY);
        String enStr = encryptByPublicKey(msgEncodeBef,RSA_PUBLIC_KEY);
        System.out.println("加密后的字符串为:" + enStr);
//        String enStr22 = encryptByPublicKey("{\"collections\":[{\"collectionTime\":\"2019-07-01 15:23:51\",\"checkType\":\"1\",\"checkModle\":\"2\",\"checkResult\":0,\"facePhoto\":\"...\",\"userName\":\"张英杰\",\"idCardNum\":\"13112719890823001X\"}],\"location\":\"116.456451_39.908683\",\"equipmentNum\":\"FC241118370034\"}\n",RSA_PUBLIC_KEY);
//
//        System.out.println("加密后的字符串为:" + enStr22);


    }

    /**
     * 分片加密
     * @param message 需要加密的字符串
     * @param publicKeyStr 公钥
     * @return
     * @throws Exception
     */
    public static String encryptByPublicKey( String message, String publicKeyStr) throws Exception
    {
// 将明文转为字节数组
        byte[] data = message.getBytes("UTF-8");
// 将公钥解码
        byte[] decoded = Base64.decodeBase64(publicKeyStr);
        RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
        Cipher cipher;
        // 使用默认RSA
                cipher = Cipher.getInstance("RSA" );//java 平台
//        cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding" );//Android 平台
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分片加密（每117个明文字节，加密一次。117为固定值，不要修改）
        while (inputLen - offSet > 0)
        {
            if ( inputLen - offSet > 117)
            {
                cache = cipher.doFinal( data, offSet, 117);
            }
            else
            {
                cache = cipher.doFinal( data, offSet, inputLen - offSet);
            }
            out.write( cache);
            i++;
            offSet = i * 117;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return  new String(Base64. encodeBase64(encryptedData),"UTF-8");
    }
    /**
     * 随机生成密钥对
     * @throws NoSuchAlgorithmException
     */
    public static void genKeyPair() throws NoSuchAlgorithmException {
        // KeyPairGenerator类用于生成公钥和私钥对，基于RSA算法生成对象
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        // 初始化密钥对生成器，密钥大小为96-1024位
        SecureRandom secureRandom = new SecureRandom();
        keyPairGen.initialize(1024,secureRandom);
        // 生成一个密钥对，保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
// 得到私钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 得到公钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
        // 得到私钥字符串
        String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
        // 将公钥和私钥保存到Map
        keyMap.put(0,publicKeyString);  //0表示公钥
        keyMap.put(1,privateKeyString);  //1表示私钥
    }
}